package Controller;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Timer;
import java.util.TimerTask;

import Model.Computation;
import View.BisectionGraph;
import View.InputPanel;
import View.MainFrame;
import View.MainPanel;
import View.NewtonGraph;
import View.OutputTable;


public class Main {
	
	private MainFrame mainFrame;
	private MainPanel mainPanel;
	private InputPanel inputPanel;
	private OutputTable outputTable;
	private NewtonGraph openGraph;
	private BisectionGraph bracketGraph;
	private Computation computation;
	
	private int counterBisection = 0;
	private int counterNewton = 0;
	
	public static void main(String[] args) {
		Main main = new Main();
	}
	
	public Main(){
		mainFrame = new MainFrame();
		mainPanel = new MainPanel();
		mainFrame.setPanel(mainPanel);
		inputPanel = mainPanel.getInputPanel();
		outputTable = mainPanel.getOutputTable();
		openGraph = mainPanel.getNewtonGraph();
		bracketGraph = mainPanel.getBisectionGraph();
		
		inputPanel.addUpdateListener(update());
		inputPanel.addBisctionPlotListener(bisection());
		inputPanel.addNewtonPlotListener(newton());
	}
	
	 private ActionListener update() {
	        return new ActionListener() {

	        @Override
	        public void actionPerformed(ActionEvent ev) {
	        	updateValues();
	        }
	        };
	    }
	    
	
	private ActionListener bisection(){
		return new ActionListener(){

			@Override
			public void actionPerformed(ActionEvent e) {
				
				final Timer timer = new Timer();
				timer.schedule( new TimerTask() {
				    public void run() {
						bisectionPlot();
						counterBisection++;
					
						if(counterBisection ==  computation.getColumnOne().size()) {
							counterBisection = 0;
							timer.cancel();
						}
				    }
				 }, 1000, 1000);
			}	
		};
	}
	
	private ActionListener newton(){
		return new ActionListener(){

			@Override
			public void actionPerformed(ActionEvent e) {
				
				final Timer timer = new Timer();
				timer.schedule( new TimerTask() {
				    public void run() {
						newtonPlot();
						counterNewton++;
					
						if(counterNewton ==  computation.getFirstColumn().size()) {
							counterNewton = 0;
							timer.cancel();
						}
				    }
				 }, 1000, 1000);
			}	
		};
	}

	public void updateValues(){
		computation = new Computation(inputPanel.getEquationTextField(), inputPanel.getIntervalFirstSpinner(), inputPanel.getIntervalSecondSpinner(), inputPanel.getToleranceTextField() , inputPanel.getMaxIterationTextField() , inputPanel.getStartTextField(), inputPanel.getIterationTextField(), inputPanel.getNewtonThresTextField());
		outputTable.updateData(computation);
		openGraph.updateValues(computation);
		bracketGraph.updateValues(computation);
	}
	
	public void bisectionPlot(){
		bracketGraph.simulatePlot(computation, counterBisection);
	}
	
	public void newtonPlot(){
		openGraph.simulatePlot(computation, counterNewton);
	}
}
